package cn.itheima.realm;

import cn.itheima.domain.system.Permission;
import cn.itheima.domain.system.Role;
import cn.itheima.domain.system.User;
import cn.itheima.service.system.PermissionService;
import cn.itheima.service.system.RoleService;
import cn.itheima.service.system.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * Created by millions on 2017/7/20.
 */
public class BosRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionService permissionService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("shiro 授权。。 ");

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        // 根据当前登录用户 查询对应角色和权限
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        List<Role> roles = roleService.findByUser(user);
        for (Role role : roles) {
            simpleAuthorizationInfo .addRole(role.getKeyword());
        }
        // 调用业务层，查询权限
        List<Permission> permissions = permissionService.findByUser(user);
        for (Permission permission : permissions) {
            simpleAuthorizationInfo.addStringPermission(permission.getKeyword());
        }

        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("shiro 认证管理。。。");

        // 转换token
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;

        // 根据用户名 查询 用户信息
        User user = userService.findByUsername(usernamePasswordToken
                .getUsername());
        if (user == null) {
            // 用户名不存在
            // 参数一： 期望登录后，保存在Subject中信息
            // 参数二： 如果返回为null 说明用户不存在，报用户名
            // 参数三 ：realm名称
            return null;
        } else {
            // 用户名存在
            // 当返回用户密码时，securityManager安全管理器，自动比较返回密码和用户输入密码是否一致
            // 如果密码一致 登录成功， 如果密码不一致 报密码错误异常
            return new SimpleAuthenticationInfo(user, user.getPassword(),
                    getName());
        }

    }
}
